home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994…tember: Reference Library / Dev.CD Sep 94.toast / Periodicals / develop / develop Issue 18 / develop 18 code / OSA Sample / Sources / ObjModelEvents.cp < prev    next >
Encoding:
Text File  |  1994-01-28  |  12.2 KB  |  510 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        ObjModelEvents.cp
  3.  
  4.     Contains:    Apple Event handlers implementation
  5.  
  6.     Developed by:    
  7.         
  8.         Paul G Smith (commstalk hq & Full Moon Software, Inc)
  9.         
  10.         you can leave messages at (UK): 0727 844232; (US): 408 253 7199
  11.         BUT I prefer to be contacted by e-mail
  12.         AppleLink:     SMITH.PG
  13.         Internet:     SMITH.PG@applelink.apple.com
  14.         
  15.         "SimpliFace" Sample code to accompany develop article
  16.         on techniques for embedding scripts in applications.
  17.  
  18.  
  19.     Apple Event handlers for SimpliFace
  20.  
  21. */
  22.  
  23. #ifndef __STDIO__
  24. #include <StdIO.h>
  25. #endif
  26.  
  27. #ifndef __MENUS__
  28. #include <Menus.h>
  29. #endif
  30. #ifndef __EVENTS__
  31. #include <Events.h>
  32. #endif
  33. #ifndef __WINDOWS__
  34. #include <Windows.h>
  35. #endif
  36. #ifndef __DIALOGS__
  37. #include <Dialogs.h>
  38. #endif
  39. #ifndef __QUICKDRAW__
  40. #include <Quickdraw.h>
  41. #endif
  42. #ifndef __RESOURCES__
  43. #include <Resources.h>
  44. #endif
  45. #ifndef __MEMORY__
  46. #include <Memory.h>
  47. #endif
  48. #ifndef __FILES__
  49. #include <Files.h>
  50. #endif
  51. #ifndef __STANDARDFILE__
  52. #include <StandardFile.h>
  53. #endif
  54. #ifndef __SYSEQU__
  55. #include <SysEqu.h>
  56. #endif
  57. #ifndef __PLSTRINGFUNCS__
  58. #include <PLStringFuncs.h>
  59. #endif
  60.  
  61. #ifndef __AERegistry__
  62. #include <AERegistry.h>
  63. #endif
  64. #ifndef __ASREGISTRY__
  65. #include <ASRegistry.h>
  66. #endif
  67. #ifndef __APPLEEVENTS__
  68. #include <AppleEvents.h>
  69. #endif
  70. #ifndef __AEOBJECTS__
  71. #include <AEObjects.h>
  72. #endif
  73. #ifndef __OSA__
  74. #include <OSA.h>
  75. #endif
  76. #ifndef __APPLESCRIPT__
  77. #include <AppleScript.h>
  78. #endif
  79. #ifndef __ASDEBUGGING__
  80. #include <ASDebugging.h>
  81. #endif
  82.  
  83. #ifndef __AEOMTOKENS__
  84. #include "ObjModelTokens.h"
  85. #endif
  86. #ifndef __AEOMEVENTS__
  87. #include "ObjModelEvents.h"
  88. #endif
  89.  
  90. #ifndef __SCRIPTOBJECTS__
  91. #include "ScriptableObjects.h"
  92. #endif
  93.  
  94. #ifndef __SCRIPTUTILS__
  95. #include "ScriptUtils.h"
  96. #endif
  97.  
  98.  
  99. extern "C" {
  100. #include "AEBuild.h"
  101. #include "AEBuildGlobals.h"
  102. #include "AEPrint.h"
  103. }
  104. #include "AEBuildErrMsgs.h"
  105.  
  106.  
  107. #include "DebugTrace.h"
  108.  
  109.  
  110.  
  111. #pragma segment AEventHandlers
  112.  
  113.  
  114. void    DumpAppleEvent(char *msg, AEDesc *desc)
  115. {
  116.     if (msg)
  117.         printf("%s", msg);
  118.         
  119.     if (desc)
  120.     {
  121.         char    buf[3000];
  122.         if (AEPrint(desc, buf, 3000) == 0)
  123.         {
  124.             printf(buf);
  125.             printf("\n");
  126.         }
  127.     }
  128. }
  129.  
  130.  
  131.  
  132. OSErr GetCurrentAppFileSpec(short *vRefNum, long *dirID, StringPtr fileName)
  133. {
  134.     OSErr                err = 0;
  135.     ProcessInfoRec        pInfo;
  136.     ProcessSerialNumber    pNum;
  137.     FSSpec                fSpec;
  138.     
  139.     err = GetCurrentProcess(&pNum);
  140.     if (!err) 
  141.     {
  142.         pInfo.processInfoLength = sizeof(pInfo);
  143.         pInfo.processName = NULL;
  144.         pInfo.processAppSpec = &fSpec;
  145.         err = GetProcessInformation(&pNum, &pInfo);
  146.     }
  147.     if (!err) 
  148.     {
  149.         *vRefNum = fSpec.vRefNum;
  150.         *dirID = fSpec.parID;
  151.         PLstrcpy((StringPtr)fileName, fSpec.name);
  152.     }    
  153.     
  154.     return err;
  155. }
  156.  
  157.  
  158. void GetCurrAppName(CStr255& appName)
  159. {
  160.     short             vRefNum;
  161.     long             dirID;
  162.     Str255            fileName;
  163.     OSErr             err = GetCurrentAppFileSpec(&vRefNum, &dirID, (StringPtr)fileName);
  164.     
  165.     if (!err)
  166.         appName = fileName;
  167. }
  168.  
  169.  
  170.  
  171.  
  172. #define optionKeyCode     0x3A
  173. #define shiftKeyCode     0x38
  174. #define cmdKeyCode         0x37
  175. #define ctrlKeyCode     0x3B
  176.  
  177. static Boolean isKeyDown(long keyCode)
  178. {
  179.     KeyMap keys;
  180.     Byte *keysBytes;
  181.     
  182.     GetKeys(keys);
  183.     
  184.     keysBytes = (Byte *)keys;
  185.  
  186.     return((keysBytes[keyCode/8] & (1 << keyCode % 8)) != 0);
  187. }
  188.  
  189.  
  190. static pascal  Boolean StdIdleFunction (EventRecord *theEventRecord,
  191.                                         long *sleepTime,
  192.                                         RgnHandle *mouseRgn)
  193. {
  194.     return    false;
  195. }
  196.  
  197.  
  198. static pascal OSErr GetAETEAEvtHandler  (AppleEvent *theEvent, 
  199.                                         AppleEvent *theReply, 
  200.                                         long theRefCon)
  201. {
  202.     OSAError         err = errAEEventNotHandled;
  203.     AEDesc            dataDesc, resultDesc;
  204.     short            languageCode;
  205.     
  206.     InitAEDescs(&dataDesc, &resultDesc, kEndOfList);
  207.     
  208.     err = AEGetParamDesc(theEvent, keyDirectObject, typeAEList, &dataDesc);
  209.     if (!err)
  210.         err = GetIntegerFromDescriptor(&dataDesc, &languageCode);
  211.     if (!err)
  212.         err = AECreateList(NULL, 0, false, &resultDesc);
  213.         
  214.     if (!err && gSimpliFace)
  215.         err = gSimpliFace->CollectAETEs(languageCode, resultDesc);
  216.         
  217.     if (!err)
  218.         err = AEPutParamDesc(theReply, keyDirectObject, &resultDesc);
  219.  
  220.     DisposeAEDescs(&dataDesc, &resultDesc, kEndOfList);
  221.     
  222.     return (OSErr)err;
  223. }
  224.  
  225.  
  226. static pascal OSErr ExecuteEventInContext (AppleEvent *theEvent, 
  227.                                         AppleEvent *theReply, 
  228.                                         long theRefCon,
  229.                                         OSAID theScriptID,
  230.                                         AEHandlerProcPtr theContextHandler,
  231.                                         long dispatchRefCon)
  232. {
  233.     OSAError            err = errAEEventNotHandled;
  234.     AEHandlerProcPtr    oldResumeProc;
  235.     long                oldRefcon;
  236.     
  237.     OSAGetResumeDispatchProc(gScriptingComponent, &oldResumeProc, &oldRefcon);
  238.     
  239.     // pass to script for handling
  240.     if (theScriptID != kOSANullScript)
  241.     {
  242.         err = OSASetResumeDispatchProc(gScriptingComponent, theContextHandler, dispatchRefCon);
  243.         if (!err)
  244.         {
  245.             err = OSADoEvent(gScriptingComponent, theEvent, theScriptID, 
  246.                              kOSAModeAlwaysInteract, theReply);
  247.         }
  248.  
  249.         OSASetResumeDispatchProc(gScriptingComponent, oldResumeProc, oldRefcon);
  250.     }
  251.     
  252.     return    (OSErr)err;
  253. }
  254.  
  255.  
  256. static pascal OSErr StdAEvtPreHandler  (AppleEvent *theEvent, 
  257.                                         AppleEvent *theReply, 
  258.                                         long theRefCon)
  259. {
  260.     OSAError             err = errAEEventNotHandled;
  261.     AEEventClass         theEvtClass;
  262.     AEEventID             theEvtID;
  263.     DescType            theType;
  264.     Size                theSize;
  265.     AEDesc                directParam, theTokenDesc;
  266.     OSAID                 theScriptID = kOSANullScript;
  267.     objModelTokenPtr     theToken = nil;
  268.     Boolean                madeAppToken = false;
  269.     DescType             theTokenClass;
  270.     
  271.     theTokenDesc.descriptorType = typeNull;
  272.     theTokenDesc.dataHandle = nil;
  273.  
  274.     // Extract the class and ID of the event from the AppleEvent
  275.     AEGetAttributePtr(theEvent, keyEventClassAttr, typeType, &theType, (Ptr) &theEvtClass, sizeof(theEvtClass), &theSize); 
  276.     AEGetAttributePtr(theEvent, keyEventIDAttr, typeType, &theType, (Ptr) &theEvtID, sizeof(theEvtID), &theSize); 
  277.     
  278.     DumpAppleEvent("••StdAEvtPreHandler: ", theEvent);
  279.     
  280.     if (isKeyDown(ctrlKeyCode) && isKeyDown(cmdKeyCode))
  281.         // do nothing if user is by-passing scripted event-handling
  282.         printf("User by-passed script\n");
  283.     else if ((theEvtClass == kCoreEventClass && theEvtID != kAEOpenApplication)
  284.             || (theEvtClass == kAECoreSuite && theEvtID != kAESetData && theEvtID != kAEGetData)
  285.             || (theEvtClass == kSignature && theEvtID == kAESystemEvent)
  286.             || (theEvtClass == kASAppleScriptSuite && theEvtID == kASSubroutineEvent))
  287.     {    // above test is to make sure we handle all the scriptable events 
  288.         // and that we skip the ones we don't want to be scriptable
  289.         err = AEGetParamDesc(theEvent, keyDirectObject, typeWildCard, &directParam);
  290.         if (!err)
  291.         {
  292.             err = AEResolve(&directParam, kAEIDoMinimum, &theTokenDesc);
  293.             AEDisposeDesc(&directParam);
  294.     
  295.             if (!err)
  296.                 theToken = ObjModelTokenFromDesc(&theTokenDesc);
  297.         }
  298.         if (err || !theToken)
  299.         {
  300.             err = MakeAppToken((TObjModelToken**)&theToken);
  301.             madeAppToken = (!err);
  302.         }
  303.     
  304.         if (theToken)
  305.             theScriptID = gScriptAdministrator->GetAttachedScript(theToken->GetTokenObj());
  306.     
  307.         // pass to script for handling
  308.         if (theScriptID != kOSANullScript)
  309.             err = ExecuteEventInContext(theEvent, theReply, theRefCon, theScriptID,
  310.                                         kOSAUseStandardDispatch, kOSADontUsePhac);
  311.         else
  312.             err = errAEEventNotHandled;
  313.             
  314.         if (theToken)
  315.             gScriptAdministrator->ReleaseAttachedScript(theToken->GetTokenObj());
  316.  
  317.         // this will dispose of the token as well as the descriptor, so
  318.         AEDisposeToken(&theTokenDesc); // DO NOT CALL until done with 'theToken'
  319.         if (madeAppToken)
  320.             delete theToken; // this will only be executed if token was made in this function
  321.     }
  322.     
  323.     if (err == errAEEventNotHandled)
  324.         printf("StdAEvtPreHandler: Apple Event not handled in pre-handler\n");
  325.     else if (err)
  326.         printf("StdAEvtPreHandler: err = %d\n", err);
  327.     
  328.     return (OSErr)err;
  329. }
  330.  
  331.  
  332. static pascal OSErr RqdAEvtHandler (AppleEvent *theEvent, 
  333.                                         AppleEvent *theReply, 
  334.                                         long theRefCon)
  335. {
  336.     OSErr            err = errAEEventNotHandled;
  337.     AEEventClass     theEvtClass;
  338.     AEEventID         theEvtID;
  339.     DescType        theType;
  340.     Size            theSize;
  341.  
  342.     // Extract the class and ID of the event from the AppleEvent
  343.     AEGetAttributePtr(theEvent, keyEventClassAttr, typeType, &theType, (Ptr) &theEvtClass, sizeof(theEvtClass), &theSize); 
  344.     AEGetAttributePtr(theEvent, keyEventIDAttr, typeType, &theType, (Ptr) &theEvtID, sizeof(theEvtID), &theSize); 
  345.  
  346.     printf("•RqdAEvtHandler: class=%.4s, id=%.4s\n", &theEvtClass, &theEvtID);
  347.  
  348.     if (theEvtClass == kCoreEventClass)
  349.     {
  350.         if (theEvtID == kAEOpenApplication)
  351.         {
  352.             if (isKeyDown(ctrlKeyCode) && isKeyDown(cmdKeyCode))
  353.                 ;
  354.             else
  355.             {
  356.                 if (gScriptAdministrator)
  357.                     gScriptAdministrator->RunStartupScript();
  358.                 err = 0;
  359.             }
  360.         }
  361.         else if (theEvtID == kAEQuitApplication)
  362.         {
  363.             err = 0;
  364.             gSimpliFace->Terminate();    // quit after next time around event loop
  365.         }
  366.     }
  367.     
  368.     printf("RqdAEvtHandler: err = %d\n", err);
  369.  
  370.     return    err;
  371. }
  372.  
  373.  
  374. static pascal OSErr StdAEvtHandler       (AppleEvent *theEvent, 
  375.                                         AppleEvent *theReply, 
  376.                                         long theRefCon)
  377. {
  378.     OSAError             err = errAEEventNotHandled;
  379.     AEEventClass         theEvtClass;
  380.     AEEventID             theEvtID;
  381.     DescType            theType;
  382.     Size                theSize;
  383.     AEDesc                directParam, theTokenDesc;
  384.     TObjModelToken         *theToken = nil;
  385.     Boolean                madeAppToken = false;
  386.     
  387.     theTokenDesc.descriptorType = typeNull;
  388.     theTokenDesc.dataHandle = nil;
  389.  
  390.     // Extract the class and ID of the event from the AppleEvent
  391.     AEGetAttributePtr(theEvent, keyEventClassAttr, typeType, &theType, (Ptr) &theEvtClass, sizeof(theEvtClass), &theSize); 
  392.     AEGetAttributePtr(theEvent, keyEventIDAttr, typeType, &theType, (Ptr) &theEvtID, sizeof(theEvtID), &theSize); 
  393.  
  394.     printf("•StdAEvtHandler: class=%.4s, id=%.4s\n", &theEvtClass, &theEvtID);
  395.  
  396.     if (theEvtClass == kAECoreSuite && theEvtID == kAECreateElement)
  397.     {
  398.         err = MakeAppToken(&theToken);
  399.         madeAppToken = (!err);
  400.     }
  401.     else
  402.     {
  403.         err = AEGetParamDesc(theEvent, keyDirectObject, typeWildCard, &directParam);
  404.         if (!err)
  405.         {
  406.             if (theEvtClass == kCoreEventClass 
  407.                  && theEvtID == kAEOpenDocuments
  408.                  && (directParam.descriptorType == typeAEList))
  409.             {
  410.                 // open documents here
  411.                 err = errAEEventNotHandled;
  412.             }
  413.             else 
  414.             {
  415.                 err = AEResolve(&directParam, kAEIDoMinimum, &theTokenDesc);
  416.         
  417.                 if (!err)
  418.                     theToken = (TObjModelToken*)ObjModelTokenFromDesc(&theTokenDesc);
  419.             }
  420.             AEDisposeDesc(&directParam);
  421.         }
  422.         
  423.         if (err)
  424.         {
  425.             err = MakeAppToken(&theToken);
  426.             madeAppToken = (!err);
  427.         }
  428.     }
  429.     if (theToken)
  430.     {
  431.         err = theToken->DispatchAppleEvent(theEvent, theReply, theEvtClass, theEvtID);
  432.     }
  433.     // this will dispose of the token as well as the descriptor, so
  434.     AEDisposeToken(&theTokenDesc); // DO NOT CALL until done with 'theToken'
  435.     if (madeAppToken)
  436.         delete theToken; // this will only be executed if token was made in this function
  437.     
  438.     printf("StdAEvtHandler: err = %ld\n", err);
  439.     
  440.     return (OSErr)err;
  441. }
  442.  
  443.  
  444. static pascal OSErr DoScriptAEvtHandler (AppleEvent *theEvent, 
  445.                                         AppleEvent *theReply, 
  446.                                         long theRefCon)
  447. {
  448.     OSAError        err = errAEEventNotHandled;
  449.     AEEventClass     theEvtClass;
  450.     AEEventID         theEvtID;
  451.     DescType        theType;
  452.     Size            theSize;
  453.  
  454.     // Extract the class and ID of the event from the AppleEvent
  455.     AEGetAttributePtr(theEvent, keyEventClassAttr, typeType, &theType, (Ptr) &theEvtClass, sizeof(theEvtClass), &theSize); 
  456.     AEGetAttributePtr(theEvent, keyEventIDAttr, typeType, &theType, (Ptr) &theEvtID, sizeof(theEvtID), &theSize); 
  457.  
  458.     printf("•DoScriptAEvtHandler: class=%.4s, id=%.4s\n", &theEvtClass, &theEvtID);
  459.  
  460.     if (gScriptAdministrator)
  461.     {
  462.         AEDesc            sourceDesc, resultDesc;
  463.  
  464.         InitAEDescs(&sourceDesc, &resultDesc, kEndOfList);
  465.         
  466.         err = AEGetParamDesc(theEvent, keyDirectObject, typeChar, &sourceDesc);
  467.         if (!err)
  468.             err = gScriptAdministrator->DoScript(&sourceDesc, &resultDesc);
  469.         if (!err)
  470.             err = AEPutParamDesc(theReply, keyDirectObject, &resultDesc);
  471.  
  472.         DisposeAEDescs(&sourceDesc, &resultDesc, kEndOfList);
  473.     }
  474.     
  475.     printf("DoScriptAEvtHandler: err = %ld\n", err);
  476.  
  477.     return    err;
  478. }
  479.  
  480.  
  481.  
  482. // installation
  483.  
  484. pascal OSErr InstallEventHandlers(void)
  485. {
  486.     OSErr err = 0;
  487.     
  488.     if (!err) err = AEInstallSpecialHandler(keyPreDispatch, (EventHandlerProcPtr)&StdAEvtPreHandler, false);
  489.  
  490.     if (!err) err = AEInstallEventHandler(kASAppleScriptSuite, kGetAETE, (EventHandlerProcPtr)&GetAETEAEvtHandler, (long)kGetAEUT, false);
  491.  
  492.     if (!err) err = AEInstallEventHandler(kCoreEventClass, typeWildCard, (EventHandlerProcPtr)&RqdAEvtHandler, 0, false);
  493.     
  494.     if (!err) err = AEInstallEventHandler(kAECoreSuite, typeWildCard, (EventHandlerProcPtr)&StdAEvtHandler, 0, false);
  495.     if (!err) err = AEInstallEventHandler(kCoreEventClass, kAEOpen, (EventHandlerProcPtr)&StdAEvtHandler, (long)kAEOpen, false);
  496.  
  497.     if (!err) err = AEInstallEventHandler(kAEMiscStandards, kAEDoScript, (EventHandlerProcPtr)&DoScriptAEvtHandler, (long)kAEDoScript, false);
  498.  
  499.     return err;
  500. }
  501.  
  502. pascal OSErr DeInstallEventHandlers(void)
  503. {
  504.     OSErr err = 0;
  505.     
  506.     return err;
  507. }
  508.  
  509.  
  510.